#include "java_bridge.h"
#include "../../core/base/timer.h"
#include "../../core/base/file_io.h"
#include "../../app_frame/bitmap.h"
#include "../../app_frame/app_frame.h"
#include <GLES/gl.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>

#include <string.h>
#include <string>

char g_appDirectory[1024] = {0};
AAssetManager* g_assetMgr = NULL;
unsigned int g_viewportWidth = 0;
unsigned int g_viewportHeight = 0;

// Main entry points of the App
bool InitApp();
void DestoryApp();
bool TimeElapse(double sec);

void Java_knyet_appframe_KNyetRenderer_SetAppDirectory(JNIEnv * env, jobject, jstring pkgname, jobject assetManager)
{
	const char *buffer = env->GetStringUTFChars( pkgname, false );
	strcpy( g_appDirectory, buffer );
	env->ReleaseStringUTFChars(pkgname, buffer);
	g_assetMgr = AAssetManager_fromJava(env, assetManager);
}

jboolean Java_knyet_appframe_KNyetRenderer_Initialize(JNIEnv*, jobject) 
{
	return InitApp();
}

void Java_knyet_appframe_KNyetRenderer_Resize(JNIEnv*, jobject, jint w, jint h) 
{
	g_viewportWidth = (unsigned int)w;
	g_viewportHeight = (unsigned int)h;
	glViewport(0, 0, w, h);
}

static KTimer timer(true);

jboolean Java_knyet_appframe_KNyetRenderer_TimeElapse(JNIEnv*, jobject) 
{
	bool result = TimeElapse(timer.Stop());
	KAppFrame::GetInstance()->mTouchEvents.Reset();
	return result;
}

void Java_knyet_appframe_KNyetRenderer_Destory(JNIEnv *, jobject)
{
	DestoryApp();
}


void Java_knyet_appframe_KNyetRenderer_OnTouchDown(JNIEnv *, jobject, jfloat x, jfloat y)
{
	KVec2 pos(x, y);
	KAppFrame::GetInstance()->mTouchEvents.PushEvent(KTouchEvent::eTouchDown, pos);
}

void Java_knyet_appframe_KNyetRenderer_OnTouchUp(JNIEnv *, jobject, jfloat x, jfloat y)
{
	KVec2 pos(x, y);
	KAppFrame::GetInstance()->mTouchEvents.PushEvent(KTouchEvent::eTouchUp, pos);
}

void Java_knyet_appframe_KNyetRenderer_OnTouchMove(JNIEnv *, jobject, jfloat x, jfloat y)
{
	KVec2 pos(x, y);
	KAppFrame::GetInstance()->mTouchEvents.PushEvent(KTouchEvent::eTouchMove, pos);
}

static char g_internalDebugString[512] = {"Android platform..."};
const char* __getDebugStatusString()
{
	return g_internalDebugString;
}

void Java_knyet_appframe_KNyetRenderer_OnPS3DS_AnalogInput(JNIEnv *, jobject, jfloat x, jfloat y, jint axisId)
{
	KGamePadState& gamePad = KAppFrame::GetInstance()->mGamePadStatus;
	switch (axisId) {
	case 0:
		gamePad.analogAxis0[0] = x;
		gamePad.analogAxis0[1] = y;
		break;
	case 1:
		gamePad.analogAxis1[0] = x;
		gamePad.analogAxis1[1] = y;
		break;
	case 2:
		gamePad.analog_L2 = x;
		gamePad.analog_R2 = y;
		break;
	}
}


void Java_knyet_appframe_KNyetRenderer_OnPS3DS_BottonInput(JNIEnv *, jobject, jboolean down_up, jint btnId)
{
	KGamePadState& gamePad = KAppFrame::GetInstance()->mGamePadStatus;
	int btnMask = 0;
	switch (btnId) {
	case 19: // KEYCODE_DPAD_UP
		btnMask = KGamePadState::eDPad_Up;
		break;
	case 20: // KEYCODE_DPAD_DOWN
		btnMask = KGamePadState::eDPad_Down;
		break;
	case 21: // KEYCODE_DPAD_LEFT
		btnMask = KGamePadState::eDPad_Left;
		break;
	case 22: // KEYCODE_DPAD_RIGHT
		btnMask = KGamePadState::eDPad_Right;
		break;
	}
	if (down_up) {
		gamePad.button_states |= btnMask;
	}
	else {
		gamePad.button_states &= ~btnMask;
	}
}
			
JNIEXPORT void Java_knyet_appframe_KNyetRenderer_SetDebugString(JNIEnv* env, jobject, jstring dbgString)
{
	const char *buffer = env->GetStringUTFChars( dbgString, false );
	strcpy(g_internalDebugString, buffer);
	env->ReleaseStringUTFChars(dbgString, buffer);
}